var config = {
  APPID: 'wx27900e3078720b6f',
  socialType: 'wx-jqfx',
  apiUrl: 'https://gate.97kid.com',
  staticUrl: 'https://gstatic.97kid.com',
  requestTimeout: 20000,
  appId: 'antYy9lOFi5mkU9QKjtYmRLM-gzGzoHsz',
  appKey: 'jqyWxLyobpsmdwsJddJlDheb'
}

var utils = (function ($) {
  return {
    noop: function () {},
    setBackUrl: function (url) {
      window.history.pushState(null, '', window.location.href)
      window.addEventListener('popstate', function () {
        window.location.href = url
      }, false)
    },
    isEmpty: function (obj) {
      if (obj === null) return true
      var type = Object.prototype.toString.call(obj)
      if (type === '[object Array]' || type === '[object String]') {
        return obj.length === 0
      }
      if (type === '[object Number]') {
        return obj === 0
      }
      for (var name in obj) {
        return false
      }
      return true
    },
    getQueryString: function (name) {
      var r1 = getMatched(name, window.location.search)
      if (r1) return r1
      var key = arguments[1]
      if (key) {
        return getMatched(name, window.localStorage.getItem(key))
      }
      return null

      function getMatched (name, string) {
        if (string) {
          var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)')
          var len = string.indexOf('?') == 0 ? 1 : 0
          var r = string.substr(len).match(reg)
          if (r != null) return unescape(r[2])
        }
        return null
      }
    },
    isWeChat: function () {
      return /(MicroMessenger)/i.test(navigator.userAgent)
    },
    isIOS: function () {
      return /iPad|iPhone|iPod/.test(navigator.platform)
    },
    isIosWebView: function () {
      return /iPad|iPhone|iPod/.test(navigator.platform) && navigator.userAgent.indexOf('Safari') === -1
    },
    isAndroid: function () {
      return /(android)/i.test(navigator.userAgent)
    },
    isAndroidWebView: function () {
      return /(android)/i.test(navigator.userAgent) && typeof android === 'object'
    },
    isWebView: function () {
      return utils.isIosWebView() || utils.isAndroidWebView()
    },
    isMobile: function () {
      return utils.isIOS() || utils.isAndroid()
    },
    parseUrlParam: function (key) {
      var match,
        pl = /\+/g, // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
          return decodeURIComponent(s.replace(pl, ' '))
        },
        query = window.location.search.substring(1),
        params = {}
      while (match = search.exec(query))
        params[decode(match[1])] = decode(match[2])
      return key ? params[key] : params
    },
    parseUrlHash: function (key) {
      var match,
        pl = /\+/g, // Regex for replacing addition symbol with a space
        search = /([^&=]+)=?([^&]*)/g,
        decode = function (s) {
          return decodeURIComponent(s.replace(pl, ' '))
        },
        query = window.location.hash.substring(1),
        params = {}
      while (match = search.exec(query))
        params[decode(match[1])] = decode(match[2])
      return key ? params[key] : params
    },
    saveUrlParam: function () {
      var param = utils.getUrlParam()
      try {
        if(param) {
          var state = Math.random().toString().slice(-6)
          delete param.state
          delete param.code
          window.localStorage.setItem('param_' + state, JSON.stringify(param))
          console.log('save url param: ', param)
          return '&state=' + state
        }
      } catch (e) {}
      return ''
    },
    recoverUrlParam: function () {
      var state = utils.getUrlParam('state')
      try {
        var param = JSON.parse(window.localStorage.getItem('param_' + state))
        delete param.state
        delete param.code
        utils.setUrlParam(param)
        window.localStorage.removeItem('param_' + state)
        return param
      } catch (e) {}
    },
    getUrlParam: function (key) {
      return utils.parseUrlParam(key)
    },
    getUrlHash: function (key) {
      return utils.parseUrlHash(key)
    },
    getUrlParamWithState: function (key) {
      if (utils.parseUrlParam(key)) return utils.parseUrlParam(key)
      else if (utils.parseUrlParam('state')) {
        try {
          return JSON.parse(utils.base64ToUtf8(utils.getUrlParam('state')))[key]
        } catch (e) {
          return ''
        }
      }
      return ''
    },
    toUrlParam: function (obj) {
      var arr = []
      for (var key in obj) {
        arr.push(key + '=' + encodeURIComponent(obj[key]))
      }
      return arr.join('&')
    },
    toUrlHash: function (obj) {
      var arr = []
      for (var key in obj) {
        arr.push(key + '=' + encodeURIComponent(obj[key]))
      }
      return arr.join('&')
    },
    /**
     * 删除指定url参数
     * @param key
     */
    deleteUrlParam: function (key) {
      var params = utils.getUrlParam()
      if (params[key]) {
        delete params[key]
        window.history.pushState(null, null, location.pathname + '?' + utils.toUrlParam(params))
      }
    },
    /**
     * 更新url参数
     * @param key
     */
    updateUrlParam: function (obj) {
      for (var key in obj) utils.deleteUrlParam(key)
      window.history.pushState(null, null, location.href + (/\?/.test(location.href) ? '&' : '?') + utils.toUrlParam(obj))
    },
    /**
     * 设置url参数
     * @param key
     */
    setUrlParam: function (obj) {
      var params = utils.getUrlParam()
      for (var key in obj) {
        if (params[key]) {
          var t = {}
          t[key] = obj[key]
          utils.updateUrlParam(t)
        } else {
          var t = {}
          t[key] = obj[key]
          window.history.pushState(null, null, location.href + (/\?/.test(location.href) ? '&' : '?') + utils.toUrlParam(t))
        }
      }
    },
    format: function (x, y) {
      var z = {
        y: x.getFullYear(),
        M: x.getMonth() + 1,
        d: x.getDate(),
        h: x.getHours(),
        m: x.getMinutes(),
        s: x.getSeconds()
      }
      return y.replace(/(y+|M+|d+|h+|m+|s+)/g, function (v) {
        return ((v.length > 1 ? '0' : '') + eval('z.' + v.slice(-1))).slice(-(v.length > 2 ? v.length : 2))
      })
    },
    showLoading: function (text) {
      if (document.getElementById('weui-loading_toast')) return
      var dvMsg = document.createElement('div')
      dvMsg.className = 'weui-loading_toast'
      dvMsg.setAttribute('id', 'weui-loading_toast')
      dvMsg.innerHTML =
        '<div class="weui-mask_transparent"></div>' +
        '<div class="weui-toast">' +
        '    <i class="weui-loading"></i>' +
        '    <p class="weui-toast__content">' + (text || '正在加载') + '</p>' +
        '</div>' +
        '<style>' +
        '.weui-loading_toast .weui-mask_transparent{position:fixed;z-index:1000;top:0;right:0;left:0;bottom:0}.weui-loading_toast .weui-toast{position:fixed;z-index:5000;width:32vw;min-height:32vw;top:48vw;left:50%;margin-left:-16vw;background:hsla(0,0%,7%,.7);text-align:center;border-radius:1.333vw;color:#fff;content:"viewport-units-buggyfill; width: 32vw; min-height: 32vw; top: 48vw; margin-left: -16vw; border-radius: 1.333vw"}.weui-loading_toast .weui-toast .weui-loading{margin:5.867vw auto 2.667vw;width:10.133vw;height:10.133vw;vertical-align:baseline;display:inline-block;-webkit-animation:loading-rotate 1s steps(12) infinite;animation:loading-rotate 1s steps(12) infinite;background:transparent url() no-repeat;background-size:100%;content:"viewport-units-buggyfill; margin: 5.867vw auto 2.667vw auto; width: 10.133vw; height: 10.133vw"}@-webkit-keyframes loading-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes loading-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.weui-loading_toast .weui-toast .weui-toast__content{margin:0 0 4vw;content:"viewport-units-buggyfill; margin: 0 0 4vw"}' +
        '</style>'
      document.body.appendChild(dvMsg)
    },
    hideLoading: function () {
      document.getElementById('weui-loading_toast') && document.getElementById('weui-loading_toast').parentNode.removeChild(document.getElementById('weui-loading_toast'))
    },
    alert: function (options, yesText) {
      if (typeof options === 'string') {
        // 兼容直接传字符串作为参数的写法
        options = {
          id: Math.ceil(Math.random() * 1000000000),
          message: options,
          yesText: typeof yesText === 'string' ? yesText : '好的',
          yes: utils.noop,
          mask: true
        }
      } else if (typeof options === 'object') {
        options.id = options.id || Math.ceil(Math.random() * 1000000000)
        options.message = options.message || '确定要这么做吗?'
        options.yesText = options.yesText || '好的'
        options.yes = options.yes || function () {}
        options.mask = !options.mask
      } else return

      // 创建提示对话框面板
      var alertMask = document.createElement('div')
      alertMask.setAttribute('id', 'alert-mask-' + options.id)
      alertMask.className = 'alert-mask hidden'
      if (!options.mask) alertMask.style.background = 'transparent'
      alertMask.innerHTML =
        '<div id="alert-box-' + options.id + '" class="alert hidden">' +
        '  <div class="title">' + options.message + '</div>' +
        '  <div id="alert-ok-' + options.id + '" class="button">' + options.yesText + '</div>' +
        '</div>' +
        '<style>' +
        '.alert-mask{position:fixed;top:0;width:100%;height:100%;background:rgba(0,0,0,.8);z-index:1005;overflow:hidden;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-transition:opacity .25s linear 0s;transition:opacity .25s linear 0s}.alert-mask .alert{width:78.667vw;background:#fff;border-radius:2.133vw;text-align:center;-webkit-transition:-webkit-transform .25s linear 0s;transition:-webkit-transform .25s linear 0s;transition:transform .25s linear 0s;transition:transform .25s linear 0s,-webkit-transform .25s linear 0s;content:"viewport-units-buggyfill; width: 78.667vw; border-radius: 2.133vw"}.alert-mask .alert .title{padding:0 5.333vw;min-height:25.6vw;font-size:4.267vw;font-family:VarelaRound-Regular;color:#676c75;line-height:6.4vw;border-bottom:.267vw solid #e7e8ea;content:"viewport-units-buggyfill; padding: 0 5.333vw; min-height: 25.6vw; font-size: 4.267vw; line-height: 6.4vw; border-bottom: 0.267vw solid #e7e8ea"}.alert-mask .alert .button,.alert-mask .alert .title{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.alert-mask .alert .button{min-height:15.2vw;font-size:4.8vw;font-family:PingFangSC-Medium;color:#32cdff;line-height:6.667vw;content:"viewport-units-buggyfill; min-height: 15.2vw; font-size: 4.8vw; line-height: 6.667vw"}.alert-mask .alert.show{-webkit-transform:scale(1);transform:scale(1)}.alert-mask .alert.hidden{-webkit-transform:scale(0);transform:scale(0)}.alert-mask.show{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.alert-mask.hidden{display:none;opacity:0}' +
        '</style>'

      add()

      // 绑定点击事件
      document.getElementById('alert-ok-' + options.id).addEventListener('click', remove, false)

      function add () {
        document.body.appendChild(alertMask)
        document.body.style.overflow = 'hidden'
        alertMask.className = 'alert-mask show'
        setTimeout(function () {
          document.getElementById('alert-box-' + options.id).className = 'alert show'
        }, 0)
      }

      function remove () {
        document.getElementById('alert-box-' + options.id).className = 'alert hidden'
        setTimeout(function () {
          alertMask.className = 'alert-mask hidden'
          document.body.style.overflow = 'auto'
          document.body.removeChild(document.getElementById('alert-mask-' + options.id))
          options.yes(true)
        }, 250)
      }
    },
    utf8ToBase64: function (str) {
      return btoa(unescape(encodeURIComponent(str)))
    },
    base64ToUtf8: function (str) {
      return decodeURIComponent(escape(atob(str)))
    },
    toast: function (options) {
      if (typeof options === 'string') {
        // 兼容直接传字符串作为参数的写法
        options = {
          message: options
        }
      } else if (typeof options === 'object') {
        options.message = options.message || ''
      } else return

      options.id = options.id || Math.ceil(Math.random() * 1000000000)
      options.timer = options.timer || 3000
      options.callback = options.callback || utils.noop
      options.mask = options.mask === undefined ? true : Boolean(options.mask)

      // 创建提示对话框面板
      var toastMask = document.createElement('div')
      toastMask.setAttribute('id', 'toast-mask-' + options.id)
      toastMask.className = 'toast-mask hidden'
      if (!options.mask) toastMask.style.background = 'transparent'
      toastMask.innerHTML =
        '<div id="toast-box-' + options.id + '" class="toast hidden">' + options.message + '</div>' +
        '<style>' +
        '.toast-mask{position:fixed;top:0;bottom:0;left:0;right:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;pointer-events:none;z-index:1004}.toast-mask .toast{min-width:45.333vw;max-width:48.667vw;padding:4vw;line-height:5.333vw;color:#fff;background-color:rgba(0,0,0,.5);border-radius:1.333vw;font-size:3.733vw;text-align:center;display:block;z-index:1009;content:"viewport-units-buggyfill; min-width: 45.333vw; max-width: 48.667vw; padding: 4vw; line-height: 5.333vw; border-radius: 1.333vw; font-size: 3.733vw"}.toast-mask .toast.show{-webkit-transform:scale(1);transform:scale(1)}.toast-mask .toast.hidden{-webkit-transform:scale(0);transform:scale(0)}.toast-mask.show{display:-webkit-box;display:-ms-flexbox;display:flex;opacity:1}.toast-mask.hidden{display:none;opacity:0}' +
        '</style>'

      add()
      setTimeout(remove, options.timer)

      function add () {
        document.body.appendChild(toastMask)
        document.body.style.overflow = 'hidden'
        toastMask.className = 'toast-mask show'
        setTimeout(function () {
          document.getElementById('toast-box-' + options.id).className = 'toast show'
        }, 0)
      }

      function remove () {
        document.getElementById('toast-box-' + options.id).className = 'toast hidden'
        setTimeout(function () {
          toastMask.className = 'toast-mask hidden'
          document.body.style.overflow = 'auto'
          document.body.removeChild(document.getElementById('toast-mask-' + options.id))
          options.callback(true)
        }, 250)
      }
    }
  }
})(window.Zepto)

;(function ($) {
  var config = {
    APPID: 'wx27900e3078720b6f',
    socialType: 'wx-jqfx',
    apiUrl: 'https://gate.97kid.com',
    staticUrl: 'https://gstatic.97kid.com',
    requestTimeout: 20000,
    appId: 'antYy9lOFi5mkU9QKjtYmRLM-gzGzoHsz',
    appKey: 'jqyWxLyobpsmdwsJddJlDheb'
  };
  $.toastAlert = function (Msg, status) {
    if (Msg === '社交账号不存在') return
    if (Msg === '未登录') return
    var $box = $('#alertBox')
    if (!$box.length) {
      $('body').append('<div id="alertBox" class="alert-box"></div>')
      $box = $('#alertBox')
    }
    if (status === 2) {
      $box.removeClass('success-toast').addClass('wrong-input')
    } else {
      $box.removeClass('wrong-input').addClass('success-toast')
    }
    $box.html(Msg)
    $box.fadeIn()

    setTimeout(function () {
      $box.fadeOut()
    }, 3000)
  }

  function Account (options) {
    this.options = $.extend({
      returnUrl: window.location.origin + window.location.pathname,
      showRegister: true,
      forceLogin: true
    }, options)
    this.accessKey = 'QKidsAccess'
    this.weChatCodeKey = 'QKidsCode'
    this.weChatCodeTimeKey = 'QKidsCodeTime'
    this.pathnameKey = 'QKidsPathname'
    this.userInfoKey = 'QKidsUserInfo'
    this.referenceKey = 'QKidsReference'
    this.channleKey = 'QKidsChannel'
    this.authCallbackKey = 'QKidsCallback'
    this.openId = 'QKidsOpenId'
    this.token = ''
    this.returnUrl = this.options.returnUrl
    this.showRegister = this.options.showRegister
    this.code = ''
    this.forceLogin = this.options.forceLogin
    this.socialBinded = true
    this.accountLoading = false
    this.close = this.options.close !== false

    var weChatCodeTime = window.localStorage.getItem(this.weChatCodeTimeKey)
    if (weChatCodeTime && weChatCodeTime < new Date().getTime()) {
      this.code = window.localStorage.getItem(this.weChatCodeKey)
    }

    var weChatInfo = navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i)
    this.inWeChat = !utils.isEmpty(weChatInfo)

    if (this.inWeChat && !utils.getQueryString('code')) {
      window.localStorage.setItem(this.pathnameKey, window.location.search)
    }

    if (utils.getQueryString('_r')) {
      window.localStorage.setItem(this.referenceKey, JSON.stringify({
        rawData: utils.getQueryString('_r'),
        expires: new Date().getTime() / 1000 + 24 * 3600
      }))
    }
    if (utils.getQueryString('_c')) {
      window.localStorage.setItem(this.channleKey, JSON.stringify({
        rawData: utils.getQueryString('_c'),
        expires: new Date().getTime() / 1000 + 24 * 3600
      }))
    }
  }

  // 登录
  Account.prototype.login = function (callback) {
    var self = this
    self.checkLoginStatus(function (err, authObj) {
      if (err) {
        callback(err)
        self._showLogin(callback)
      } else {
        callback(err, authObj)
      }
    })
  }

  // 获取用户信息
  Account.prototype.getUserInfo = function (callback) {
    var self = this
    self.checkLoginStatus(function (err) {
      if (err) {
        if (self.forceLogin) {
          self.login(function (err) {
            if (err) callback(err)
            else self._getUserInfo(callback)
          })
        } else {
          callback(err)
        }
      } else {
        self._getUserInfo(callback)
      }
    })
  }

  Account.prototype.checkLoginStatus = function (callback) {
    var self = this
    var weChatCode = utils.getQueryString('code')
    if (!weChatCode && window.localStorage.getItem(self.weChatCodeTimeKey) > new Date().getTime()) {
      weChatCode = window.localStorage.getItem(self.weChatCodeKey)
    }
    self.code = weChatCode
    self._getAccess(function (err, token) {
      if (err) {
        if (self.inWeChat) {
          // 存在from可能为分享消息，code可能与当前账号不符，重新授权
          var from = utils.getQueryString('from')
          if (from && self.forceLogin) {
            return self._getWechatAccess()
          }
          if (weChatCode) {
            window.localStorage.setItem(self.weChatCodeKey, weChatCode)
            window.localStorage.setItem(self.weChatCodeTimeKey, new Date().getTime() + 110 * 60 * 1000)
            self.ajax({
              auth: false,
              type: 'POST',
              path: '/s/user/login/social',
              data: {
                socialCode: weChatCode,
                socialType: config.socialType,
                checkVersion: 0
              },
              success: function (result) {
                self.socialBinded = true
                self._saveToken(result)
                self.token = result.access_token
                self._saveOpenId(result.socialId)
                callback(null, result)
              },
              error: function (err) {
                self.socialBinded = false
                callback(err)
              }
            })
          } else {
            if (self.forceLogin) return self._getWechatAccess()
            return callback(err)
          }
        } else {
          callback(err)
        }
      } else {
        callback(null, token)
      }
    })
  }

  Account.prototype.ajax = function (options) {
    var self = this
    var opt = $.extend({
      auth: true
    }, options)
    if (opt.auth) {
      self.login(function () {
        opt.headers = $.extend(opt.headers || {}, {
          Authorization: 'Bearer ' + self.token
        })
        self._ajax(opt)
      })
    } else {
      self._ajax(opt)
    }
  }

  Account.prototype._ajax = function (options) {
    if (!options.ignoreLoading) {
      utils.showLoading()
    }
    $.ajax({
      type: options.type || 'GET',
      url: config.apiUrl + options.path,
      data: options.data || {},
      headers: options.headers || {},
      dataType: 'json',
      async: options.async,
      timeout: config.requestTimeout,
      success: function (result) {
        if (!options.ignoreLoading) {
          utils.hideLoading()
        }
        if (options.success) options.success(result)
      },
      error: function (xhr, errorType, error) {
        if (!options.ignoreLoading) {
          utils.hideLoading()
        }
        var apiError = {}
        try {
          apiError = JSON.parse(xhr.responseText)
        } catch (e) {
          if ($('meta[name="_token"]').attr('content')) {
            $.ajax({
              type: 'POST',
              url: '/wx/error',
              data: {
                type: options.type || 'GET',
                uri: config.apiUrl + options.path,
                data: options.data,
                status: xhr.status,
                errorType: errorType,
                error: error,
              },
              headers: {
                'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
              }
            })
          }
          apiError = {code: 'unknown.error', message: '网络请求错误'}
        }
        if (options.error) options.error(apiError)
      }
    })
  }

  Account.prototype._getUserInfo = function (callback) {
    var self = this
    self.ajax({
      path: '/s/user',
      success: function (result) {
        window.localStorage.setItem(self.userInfoKey, JSON.stringify(result))
        $('#current-account').text(result.mobile)
        $('#account-info').show()
        callback(null, result)
      },
      error: function (err) {
        callback(err)
      }
    })
  }

  Account.prototype._getAccess = function (callback) {
    var self = this

    if (self.inWeChat) {
      var socialId = window.localStorage.getItem(self.openId)
      if (self.socialBinded && !socialId) return callback({code: 'error'})
    }

    try {
      var accessString = window.localStorage.getItem(self.accessKey)
      if (!accessString) {
        return callback({code: 'access.not.exist', message: '未登录'})
      }
      var access = JSON.parse(accessString)
      var token = access.access_token
      var expireAt = access.expire_at
      var refreshToken = access.refresh_token
      self.token = token
      if (new Date().getTime() / 1000 < expireAt) {
        callback(null, token)
      } else {
        self.ajax({
          auth: false,
          type: 'POST',
          path: '/s/user/refresh',
          data: {
            refresh_token: refreshToken
          },
          success: function (result) {
            self._saveToken(result)
            self.token = result.access_token
            callback(null, result.access_token)
          },
          error: function (err) {
            callback(err)
          }
        })
      }
    } catch (e) {
      callback(e)
    }
  }

  Account.prototype._tryUnbindSocial = function () {
    var self = this
    var accessString = window.localStorage.getItem(self.accessKey)
    var weChatCode = window.localStorage.getItem(self.weChatCodeKey)
    var weChatCodeTime = window.localStorage.getItem(self.weChatCodeTimeKey)
    if (self.inWeChat && accessString) {
      self.ajax({
        type: 'DELETE',
        path: '/s/user/social/wx-jqfx',
        async: false
      })
    }
    if (self.inWeChat && weChatCodeTime && (!weChatCode || weChatCodeTime < new Date().getTime())) {
      return self._getWechatAccess()
    }
  }

  Account.prototype._saveToken = function (tokenObj) {
    this.token = tokenObj.access_token
    tokenObj.expire_at = new Date().getTime() / 1000 + tokenObj.expires_in - 600
    window.localStorage.setItem(this.accessKey, JSON.stringify(tokenObj))
  }

  Account.prototype._saveOpenId = function (openId) {
    window.localStorage.setItem(this.openId, openId)
  }

  Account.prototype._getWechatAccess = function () {
    window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + config.APPID + '&redirect_uri=' + encodeURI(this.returnUrl) + '&response_type=code&scope=snsapi_userinfo' + utils.saveUrlParam() + '#wechat_redirect'
  }

  Account.prototype.setAuthCallback = function (func) {
    window.localStorage.setItem(this.authCallbackKey, func || '')
  }

  Account.prototype.getAuthCallback = function () {
    return window.localStorage.getItem(this.authCallbackKey)
  }

  Account.prototype._showLogin = function (callback, loginFirst) {
    var self = this
    if (self.inWeChat) {
      var weChatCode = utils.getQueryString('code')
      if (!weChatCode && window.localStorage.getItem(self.weChatCodeTimeKey) > new Date().getTime()) {
        weChatCode = window.localStorage.getItem(self.weChatCodeKey)
      }
      if (!weChatCode) {
        return self._getWechatAccess()
      }
    }
    var html =
      '<div id="login" class="login-mask">' +
      '  <div class="login-box">' +
      '    <form id="loginForm" class="login-form">' +
      '      <div class="login-title">手机号登录</div>' +
      '      <input id="loginMobile" placeholder="手机号" type="tel" maxlength="11">' +
      '      <input id="loginPassword" placeholder="密码" type="password" maxlength="12">' +
      '      <div id="loginBtn" class="submit-btn">登录</div>' +
      '      <div id="forgetPassword">忘记密码?</div>' +
      '      <div id="switchRegister">注册账号</div>' +
      '    </form>' +
      '    <form id="registerForm" class="register-form">' +
      '      <div class="login-title">新用户注册</div>' +
      '      <input id="regMobile" placeholder="手机号" type="tel" maxlength="11">' +
      '      <input id="regSmsCode" placeholder="验证码" type="tel" maxlength="4">' +
      '      <div id="regSmsBtn" class="send-btn">获取验证码</div>' +
      '      <input id="regPassword" placeholder="6～12位新密码，数字加字母" type="password" maxlength="12">' +
      '      <span id="showHideRegPassword" class="hide"></span>' +
      '      <div id="regBtn" class="submit-btn">注册</div>' +
      '      <div id="switchLogin">已有账号？<span class="underline">立即登录</span></div>' +
      '    </form>' +
      '    <form id="resetForm" class="reset-form">' +
      '      <div id="backLogin"></div>' +
      '      <div class="login-title">找回密码</div>' +
      '      <input id="resetMobile" placeholder="手机号" type="tel" maxlength="11">' +
      '      <input id="resetSmsCode" placeholder="验证码" type="tel" maxlength="4">' +
      '      <div id="resetSmsBtn" class="send-btn">获取验证码</div>' +
      '      <input id="resetPassword" placeholder="6～12位新密码，数字加字母" type="password" maxlength="12">' +
      '      <span id="showHideResetPassword" class="hide"></span>' +
      '      <div id="resetBtn" class="submit-btn">完成并登录</div>' +
      '    </form>' +
      '  </div>' +
      '</div>' +
      '<style>' +
      '.login-mask{position:fixed;width:100%;height:100%;top:0;background-color:rgba(0,0,0,.8);z-index:1003;overflow:hidden;display:none;font-family:VarelaRound-Regular,PingFangSC-Light,Microsoft YaHei}.login-mask *{-webkit-box-sizing:border-box;box-sizing:border-box}.login-mask .login-box{width:78.667vw;margin:35% auto;overflow:hidden;background-color:#fff;border-radius:3.2vw;position:relative;padding:0;content:"viewport-units-buggyfill; width: 78.667vw; border-radius: 3.2vw"}.login-mask form{margin:8.533vw auto;content:"viewport-units-buggyfill; margin: 8.533vw auto"}.login-mask input{margin:2.133vw auto 0;display:block;width:68vw;height:12.267vw;line-height:normal;font-size:3.733vw;font-family:VarelaRound-Regular;text-indent:5.333vw;outline:none;color:#4b5058;background:#fff;border-radius:6.133vw;border:.267vw solid #f2f2f2;-webkit-appearance:none;-moz-appearance:none;appearance:none;content:"viewport-units-buggyfill; margin: 2.133vw auto 0 auto; width: 68vw; height: 12.267vw; font-size: 3.733vw; text-indent: 5.333vw; border-radius: 6.133vw; border: 0.267vw solid #f2f2f2"}.login-mask input:-ms-input-placeholder,.login-mask input::-ms-input-placeholder{font-weight:300;font-family:PingFangSC-Light;color:#c1c1c1}.login-mask input::-webkit-input-placeholder{font-weight:300;font-family:PingFangSC-Light;color:#c1c1c1}.login-mask input:-ms-input-placeholder,.login-mask input::-ms-input-placeholder{font-weight:300;font-family:PingFangSC-Light;color:#c1c1c1}.login-mask input::placeholder{font-weight:300;font-family:PingFangSC-Light;color:#c1c1c1}.login-mask .login-title{height:7.467vw;margin-bottom:6.4vw;line-height:7.467vw;font-size:5.333vw;font-family:PingFangSC-Medium;color:#4b5058;text-align:center;content:"viewport-units-buggyfill; height: 7.467vw; margin-bottom: 6.4vw; line-height: 7.467vw; font-size: 5.333vw"}.login-mask .submit-btn{display:block;margin:2.133vw auto 0;width:68vw;height:12.8vw;line-height:12.8vw;background:hsla(216,8%,63%,.6);border-radius:6.4vw;font-size:4.267vw;font-family:PingFangSC-Medium;color:#e5e6e9;text-align:center;content:"viewport-units-buggyfill; margin: 2.133vw auto 0 auto; width: 68vw; height: 12.8vw; line-height: 12.8vw; border-radius: 6.4vw; font-size: 4.267vw"}.login-mask .active{background:#32cdff;color:#fff}.login-mask .send-btn{display:inline-block;width:24vw;height:12.8vw;line-height:12.8vw;font-size:3.733vw;font-weight:300;font-family:PingFangSC-Light;color:#4b5058;position:absolute;top:36.8vw;right:5.067vw;content:"viewport-units-buggyfill; width: 24vw; height: 12.8vw; line-height: 12.8vw; font-size: 3.733vw; top: 36.8vw; right: 5.067vw"}.login-mask .underline{text-decoration:underline}.login-mask #forgetPassword{margin:4.267vw 10.933vw 0 17.067vw;color:#999fa8;content:"viewport-units-buggyfill; margin: 4.267vw 10.933vw 0 17.067vw; width: 18.667vw; height: 5.333vw; line-height: 5.333vw; font-size: 3.733vw"}.login-mask #forgetPassword,.login-mask #switchRegister{display:inline-block;width:18.667vw;height:5.333vw;line-height:5.333vw;font-size:3.733vw;font-weight:300;font-family:PingFangSC-Light}.login-mask #switchRegister{color:#4b5058;content:"viewport-units-buggyfill; width: 18.667vw; height: 5.333vw; line-height: 5.333vw; font-size: 3.733vw"}.login-mask #backLogin{position:absolute;top:9.333vw;left:6.667vw;width:6.4vw;height:6.4vw;background:url("");background-size:6.4vw 6.4vw;content:"viewport-units-buggyfill; top: 9.333vw; left: 6.667vw; width: 6.4vw; height: 6.4vw; background-size: 6.4vw 6.4vw"}.login-mask #switchLogin{margin:4.267vw auto 0;text-align:center;height:5.333vw;font-size:3.733vw;font-family:PingFangSC-Regular;color:#4b5058;content:"viewport-units-buggyfill; margin: 4.267vw auto 0 auto; height: 5.333vw; font-size: 3.733vw"}.login-mask #showHideRegPassword,.login-mask #showHideResetPassword{position:absolute;display:block;top:51.2vw;right:5.333vw;width:13.6vw;height:12.267vw;background-size:4.267vw 4.267vw;background-repeat:no-repeat;background-position:4vw 4vw;content:"viewport-units-buggyfill; top: 51.2vw; right: 5.333vw; width: 13.6vw; height: 12.267vw; background-size: 4.267vw 4.267vw; background-position: 4vw 4vw"}.login-mask #showHideRegPassword.show,.login-mask #showHideResetPassword.show{background-image:url("")}.login-mask #showHideRegPassword.hide,.login-mask #showHideResetPassword.hide{background-image:url("")}' +
      '</style>'

    if (!$('#login').length) $('body').append(html)

    self._initLoginEvent(callback)

    $('#resetForm, #loginForm').css('display', 'none')
    $('#registerForm').css('display', 'block')
    $('.login-mask').css('display', 'block')
    $('body').css({'position': 'fixed', 'width': '100%'})
  }

  //限制输入数字
  $.fn.onlyNum = function () {
    $(this).keypress(function (event) {
      var eventObj = event || e
      var keyCode = eventObj.keyCode || eventObj.which
      if ((keyCode >= 48 && keyCode <= 57))
        return true
      else
        return false
    }).focus(function () {
      //禁用输入法
      this.style.imeMode = 'disabled'
    }).bind('paste', function () {
      //获取剪切板的内容
      var clipboard = window.event.clipboardData.getData('text')
      if (/^\d+$/.test(clipboard))
        return true
      else
        return false
    })
  }

  Account.prototype._initLoginEvent = function (callback) {
    if (typeof callback !== 'function') callback = function () {}
    var self = this

    // 表单校验
    $('#login input').off('input change').on('input change', function () {
      if ($('#loginMobile').val().length  === 11 &&
          $('#loginPassword').val().length >= 6 &&
          $('#loginPassword').val().length <= 12 &&
          /^[0-9]*$/.test($('#loginMobile').val()) &&
          /^[0-9a-zA-Z]*$/.test($('#loginPassword').val())) {
        $('#loginBtn').addClass('active')
      } else {
        $('#loginBtn').removeClass('active')
      }
      if ($('#regMobile').val().length  === 11 &&
          $('#regSmsCode').val().length === 4 &&
          $('#regPassword').val().length >= 6 &&
          $('#regPassword').val().length <= 12 &&
          /^[0-9]*$/.test($('#regMobile').val()) &&
          /^[0-9]*$/.test($('#regSmsCode').val()) &&
          /^[0-9a-zA-Z]*$/.test($('#regPassword').val())) {
        $('#regBtn').addClass('active')
      } else {
        $('#regBtn').removeClass('active')
      }
      if ($('#resetMobile').val().length  === 11 &&
          $('#resetSmsCode').val().length === 4 &&
          $('#resetPassword').val().length >= 6 &&
          $('#resetPassword').val().length <= 12 &&
          /^[0-9]*$/.test($('#resetMobile').val()) &&
          /^[0-9]*$/.test($('#resetSmsCode').val()) &&
          /^[0-9a-zA-Z]*$/.test($('#resetPassword').val())) {
        $('#resetBtn').addClass('active')
      } else {
        $('#resetBtn').removeClass('active')
      }
    })

    // 显示隐藏密码
    $('#showHideRegPassword').off('click').on('click', function () {
      if ($('#showHideRegPassword').attr('class') === 'hide') {
        $('#regPassword').attr('type', 'text')
        $('#showHideRegPassword').attr('class', 'show')
      } else {
        $('#regPassword').attr('type', 'password')
        $('#showHideRegPassword').attr('class', 'hide')
      }
    })
    $('#showHideResetPassword').off('click').on('click', function () {
      if ($('#showHideResetPassword').attr('class') === 'hide') {
        $('#resetPassword').attr('type', 'text')
        $('#showHideResetPassword').attr('class', 'show')
      } else {
        $('#resetPassword').attr('type', 'password')
        $('#showHideResetPassword').attr('class', 'hide')
      }
    })

    // 验证码只能是数字
    $('#loginMobile, #regMobile, #resetMobile, #regSmsCode, #resetSmsCode').onlyNum()

    // 清空密码和按钮状态
    $('#loginPassword, #regSmsCode, #regPassword, #resetSmsCode, #resetPassword').val('')
    $('#loginBtn, #regBtn, #resetBtn').removeClass('active')

    // 阻止关闭点击冒泡
    $('.login-box').off('click').on('click', function (e) {
      e.stopPropagation()
    })

    // 已有账号
    $('#switchLogin').off('click').on('click', function () {
      $('#resetForm, #registerForm').css('display', 'none')
      $('#loginForm').css('display', 'block')
    })
    // 还没有账号
    $('#switchRegister').off('click').on('click', function () {
      $('#loginForm, #resetForm').css('display', 'none')
      $('#registerForm').css('display', 'block')
    })
    // 忘记密码
    $('#forgetPassword').off('click').on('click', function () {
      $('#loginForm, #registerForm').css('display', 'none')
      $('#resetForm').css('display', 'block')
    })
    // 返回登录
    $('#backLogin').off('click').on('click', function () {
      $('#resetForm, #registerForm').css('display', 'none')
      $('#loginForm').css('display', 'block')
    })

    // 关闭登录窗口
    $('.login-mask').click(function () {
      if (self.close) {
        $('.login-mask').css('display', 'none')
        $('body').css({'position': 'relative'})
      }
    })

    var countdown = 60

    // 发送注册验证码
    $('#regSmsBtn').off('click').on('click', function () {

      if (countdown !== 60)
        return

      var mobile = $.trim($('#regMobile').val())

      if (!checkMobile(mobile)) false

      self.ajax({
        auth: false,
        type: 'POST',
        path: '/s/user/sms/register',
        data: {
          mobile: mobile
        },
        success: function () {
          setTime($('#regSmsBtn'))
          utils.toast('验证码已经发送')
        },
        error: function (error) {
          utils.toast(error.message)
        }
      })

    })

    // 注册用户
    $('#regBtn').off('click').on('click', function () {
      if (self.accountLoading) return
      self.accountLoading = true
      var mobile = $.trim($('#regMobile').val())
      var verifyCode = $.trim($('#regSmsCode').val())
      var password = $.trim($('#regPassword').val())

      //检查手机
      if (!checkMobile(mobile)) {
        self.accountLoading = false
        return false
      }

      //检查验证码
      if (verifyCode.length !== 4) {
        utils.toast('手机验证码为4位数字')
        self.accountLoading = false
        return false
      }

      //检查密码
      if (!checkPassword(password)) {
        self.accountLoading = false
        return false
      }

      //查找reference

      var reference = ''
      try {
        var referenceObj = JSON.parse(window.localStorage.getItem(self.referenceKey))
        if (referenceObj && referenceObj.rawData && new Date().getTime() / 1000 < referenceObj.expires) {
          reference = referenceObj.rawData
        }
      } catch (e) {
        console.log(e)
      }
      var channel = ''
      try {
        var channelObj = JSON.parse(window.localStorage.getItem(self.channleKey))
        if (channelObj && channelObj.rawData && new Date().getTime() / 1000 < channelObj.expires) {
          channel = channelObj.rawData
        }
      } catch (e) {
        console.log(e)
      }

      self.ajax({
        auth: false,
        type: 'POST',
        path: (self.inWeChat && self.code) ? '/s/user/register/withSocial' : '/s/user/register',
        data: {
          mobile: mobile,
          smsCode: verifyCode,
          password: password,
          reference: reference,
          channel: channel,
          socialType: config.socialType,
          socialCode: self.code
        },
        success: function (data) {
          self.accountLoading = false
          _hideLogin(mobile)
          self.socialBinded = true
          self._saveToken(data)
          self._saveOpenId(data.socialId)
          callback(null, data)
        },
        error: function (err) {
          self.accountLoading = false
          utils.toast(err.message)
          callback(err)
        }
      })
    })

    // 登录
    $('#loginBtn').off('click').on('click', function () {
      if (self.accountLoading) return
      self.accountLoading = true
      var mobile = $.trim($('#loginMobile').val())
      var password = $.trim($('#loginPassword').val())

      if (!checkMobile(mobile)) {
        self.accountLoading = false
        return false
      }
      //检查密码
      if (!checkPassword(password)) {
        self.accountLoading = false
        return false
      }
      self._tryUnbindSocial()

      self.ajax({
        auth: false,
        type: 'POST',
        path: '/s/user/login',
        data: {
          mobile: mobile,
          password: password,
          checkVersion: 0
        },
        beforeSend: function () {
          self.accountLoading = false
        },
        success: function (data) {
          self.accountLoading = false
          _hideLogin(mobile)
          self._saveToken(data)
          if (self.inWeChat) {
            self.ajax({
              type: 'POST',
              path: '/s/user/social',
              data: {
                socialType: config.socialType,
                socialCode: self.code
              },
              success: function (result) {
                self.socialBinded = true
                self._saveOpenId(result.socialId)
                callback(null, data)
              }
            })
          } else {
            callback(null, data)
          }

        },
        error: function (err) {
          self.accountLoading = false
          utils.toast(err.message)
          $('#loginBtn').find('.loading-icon').show()
          $('#loginBtn').find('.right-arrow-icon').show().siblings('.loading-icon').hide()

        }
      })

    })

    // 发送重设密码验证码
    countdown = 60
    $('#resetSmsBtn').off('click').on('click', function () {
      if (countdown !== 60)
        return

      var mobile = $.trim($('#resetMobile').val())

      if (!checkMobile(mobile)) false

      self.ajax({
        auth: false,
        type: 'POST',
        path: '/s/user/sms/password',
        data: {
          mobile: mobile
        },
        dataType: 'json',
        success: function (result) {
          setTime($('#resetSmsBtn'))
          utils.toast('验证码已经发送')
        },
        error: function (err) {
          utils.toast(err.message)
        }
      })
    })

    //重置密码
    $('#resetBtn').off('click').on('click', function () {
      if (self.accountLoading) return
      self.accountLoading = true

      var mobile = $.trim($('#resetMobile').val())
      var verifyCode = $.trim($('#resetSmsCode').val())
      var password = $.trim($('#resetPassword').val())

      //检查手机
      if (!checkMobile(mobile)) {
        self.accountLoading = false
        return false
      }

      //检查验证码
      if (verifyCode.length !== 4) {
        utils.toast('手机验证码为4位数字')
        self.accountLoading = false
        return false
      }

      //检查密码
      if (!checkPassword(password)) {
        self.accountLoading = false
        return false
      }

      self.ajax({
        auth: false,
        type: 'POST',
        path: '/s/user/password/reset',
        data: {
          mobile: mobile,
          smsCode: verifyCode,
          password: password
        },
        success: function (data) {
          self.accountLoading = false
          utils.toast('密码成功重置,请登录')
          $('#resetForm, #registerForm').css('display', 'none')
          $('#loginForm').css('display', 'block')
        },

        error: function (err) {
          self.accountLoading = false
          utils.toast(err.message)
        }
      })
    })

    //启动计时器
    function setTime (obj) {
      if (countdown === 0) {
        obj.attr('disabled', false)
        obj.text('发送验证码')
        countdown = 60
        return
      } else {
        obj.attr('disabled', false)
        obj.text(countdown + 's')
      }
      countdown--

      setTimeout(function () {
        setTime(obj)
      }, 1000)
    }

    // 检查手机号
    function checkMobile (mobile) {
      var pregMobile = /^1\d{10}$/
      if ($.trim(mobile) === '') {
        utils.toast('手机号不能为空')
        return false
      }

      if (!pregMobile.test(mobile)) {
        utils.toast('不是有效的手机号')
        return false
      }
      return true
    }

    // 检查密码
    function checkPassword (password) {
      //字段值仅允许字母、数字、破折号（-）以及底线（_）
      var pregPassword = /^[0-9A-Za-z_-]{6,30}$/
      if (password === '' || password.length < 6 || password.length > 32) {
        utils.toast('密码长度为6-32位')
        return false
      }

      if (!pregPassword.test(password)) {
        utils.toast('密码长度6到10位,仅允许字母，数字，破折号，底线 ')
        return false
      }
      return true
    }

    function _hideLogin (mobile) {
      // 删除本地userid
      localStorage.removeItem('userId')
      utils.toast('成功登录')
      $('.login-mask').css('display', 'none')
      $('body').css({'position': 'relative'})

      //记录当前手机号
      localStorage.setItem('mobile', mobile)
      $('#current-account').text(mobile.replace(mobile.substr(3, 4), '****'))
      $('#account-info').show()
    }
  }

  // Account.prototype._getRecommendation = function(callback) {
  //     var self = this;
  //     self.checkLoginStatus(function (err, authObj) {
  //         if (err) {
  //             self._showLogin(callback);
  //         } else {
  //             callback(err, authObj);
  //         }
  //     });
  // };

  Account.init = function (options) {
    return new Account(options)
  }

  if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
    define(function () {
      return Account
    })
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = Account.init
    module.exports.Account = Account
  }
  window.Account = Account
})(window.Zepto)
